<template>
	<el-container class="chat">
		<el-header class="chat-title">
			<h1 style="font-size: 18px">{{ localChatRoom.name }}</h1>
		</el-header>
		<el-main class="chat-body">
			<el-container class="chat-container">
				<div class="message-container el-scrollbar" ref="messageContainer">
					<div v-for="message in messages" :key="message.id" class="message">
						<div :class="['username', message.isMine ? 'mine' : 'theirs']">
							{{ message.username }}
						</div>
						<div :class="['content', message.isMine ? 'mine' : 'theirs']"
							 v-html="md.render(message.content)">
						</div>
					</div>
				</div>
				<div class="input-container">
					<el-input v-model="newMessage" type="textarea" resize="none" placeholder="Type your message..."
							  @keyup.enter="handleKeyDown" class="input-area"/>
				</div>
			</el-container>
		</el-main>
	</el-container>
</template>

<script>
import {ElMessage} from 'element-plus';
import MarkdownIt from "markdown-it";
import "katex/dist/katex.min.css";
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css';

const md = new MarkdownIt({
	html: true,
	linkify: true,
	typographer: true,
	quotes: '“”‘’',
	highlight: function (str, lang) {
		if (lang && hljs.getLanguage(lang)) {
			try {
				return '<pre class="hljs"><code>' +
					hljs.highlight(str, {language: lang, ignoreIllegals: true}).value +
					'</code></pre>';
			} catch (__) {
			}
		}

		return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
	}
}).use(require("markdown-it-katex"));

export default {
	name: 'Chat',
	props: {
		currentChatRoom: {
			type: Object,
			required: true,
			default: () => ({}),
		},
	},
	data() {
		return {
			socket: null,
			messages: [],
			newMessage: '',
			localChatRoom: {},
			md: md
		};
	},

	mounted() {
		this.initiateChat();
	},

	beforeUnmount() {
		if (this.socket) {
			this.socket.close();
		}
	},

	methods: {
		handleKeyDown(event) {
			if (event.keyCode === 13) {
				if (!event.shiftKey) {
					this.sendMessage();
				}
			}
		},

		initiateChat() {
			if (this.socket) {
				this.socket.close();
			}
			const local = localStorage.getItem('currentChatRoom');
			if (local) {
				this.localChatRoom = JSON.parse(local);
			}
			if (!this.currentChatRoom) {
				ElMessage.error('Please select a chat room first.');
				return;
			}
			this.connectWebSocket();
			this.fetchMessages();
		},

		connectWebSocket() {
			try {
				this.socket = this.$api.connectWebSocket(this.$route.params.id);
				this.socket.onerror = (error) => {
					console.error(error);
					ElMessage.error('Failed to connect to the chat server.');
				};
			} catch (error) {
				console.error(error);
				ElMessage.error('Failed to connect to the chat server.');
			}
		},

		async fetchMessages() {
			try {
				const response = await this.$api.fetchChatMessages(this.localChatRoom.id);
				if (response.data.code === 200) {
					this.messages = response.data.data.map(msg => ({
						id: msg.id,
						username: msg.user, // 假设你有方式获取用户名
						content: msg.content,
						timestamp: msg.timestamp,
						isMine: msg.user === localStorage.getItem('username') // 检查消息是否为用户所发
					}));
				} else {
					console.error('Failed to fetch messages:', response.data.msg);
				}
			} catch (error) {
				console.error('Error fetching messages:', error);
				ElMessage.error('Error fetching messages from server.');
			}
			await this.$nextTick(() => {
				this.$refs.messageContainer.scrollTop = this.$refs.messageContainer.scrollHeight;
			});
		},

		sendMessage() {
			this.newMessage = this.newMessage.trim();
			this.newMessage.replace(/\s+$/, '');
			if (this.newMessage === '')
				return;
			this.$api.sendMessage(this.socket, this.localChatRoom.id, localStorage.getItem('id'), this.newMessage);
			if (this.newMessage.includes('@deep')) {
				this.sendToDeep();
			}
			this.newMessage = '';
			this.$nextTick(() => {
				this.$refs.messageContainer.scrollTop = this.$refs.messageContainer.scrollHeight;
			});
		},

		sendToDeep() {
			const toAImessages = [{
				content: this.newMessage,
				isMine: true,
			}];
			this.$api.createChatCompletion(toAImessages).then(response => {
				this.$api.sendMessage(this.socket, this.localChatRoom.id, 666, response.data.choices[0].message.content);
			}).catch(error => {
				console.error('Error sending message to deep:', error);
				ElMessage.error('Error sending message to deep.');
			});
		},
	},
	watch: {
		'$route'(to, from) {
			if (to.params.id !== from.params.id) {
				this.initiateChat();
			}
		},
		// 监听websocket消息
		socket: {
			handler(val) {
				if (val) {
					val.onmessage = (event) => {
						const message = JSON.parse(event.data);
						this.messages.push({
							username: message.username,
							content: message.content,
							isMine: message.username === localStorage.getItem('username')
						});
						this.$nextTick(() => {
							this.$refs.messageContainer.scrollTop = this.$refs.messageContainer.scrollHeight;
						});
					};
				}
			},
			immediate: true,
		},
	},
};
</script>

<style>
* {
	user-select: text;
	padding: 0;
	margin: 0;
}

.chat {
	width: 100%;
	background-color: rgba(242, 242, 242, 0.1);
	backdrop-filter: blur(10px);
	border-bottom-right-radius: 1rem;
	border-top-right-radius: 1rem;
}

.chat-title {
	height: 65px;
	color: #000;
	border-bottom: 1px solid #ccc;

	display: flex;
	align-items: center;
	justify-content: left;

	background-color: rgba(242, 242, 242, 0.4);
	backdrop-filter: blur(10px);
	border-top-right-radius: 1rem;
}

.chat-body {
	padding: 0;
	margin: 0;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.chat-container {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.message-container {
	padding: 0.5rem 1rem;
	overflow-y: auto;
	flex-grow: 1;
}

.message {
	display: flex;
	flex-direction: column;
	margin-bottom: 2rem;
	margin-top: 2rem;
}

.username {
	background-color: transparent;
	color: #000;
	font-size: 0.8rem;
	margin-bottom: 0.5rem;
}

.username.mine {
	text-align: right;
	align-self: flex-end;
}

.username.theirs {
	text-align: left;
	align-self: flex-start;
}

.content {
	border-radius: 1rem;
	max-width: 70%;
	padding: 0.5rem 1rem;
	white-space: pre-wrap;
}

.content ol {
	margin: 1rem;
}

.content p {
	margin: 0;
	padding: 0;
	display: inline;
	white-space: pre-wrap;
}

.content pre {
	border-radius: 1rem;
	background-color: #f7f7f7;
}

.content.mine {
	background-color: #409eff;
	color: white;
	align-self: flex-end;
}

.content.theirs {
	background-color: white;
	color: black;
	align-self: flex-start;
}

.input-container {
	padding: 0;
	display: flex;
	width: 100%;
	height: 25%;
}

.input-area {
	border-bottom-right-radius: 1rem;
	height: 100%;

}

.el-textarea {
	border: none;
	border-radius: 0 0 1rem 0;

	.el-textarea__inner {
		border: none;
		border-radius: 0 0 1rem 0;
		height: 100%;
		white-space: pre-wrap;
		background-color: rgba(242, 242, 242, 0.4);

	}
}
</style>